偽類 (pseudo class) 是一種特別的 CSS 語法,它只會在指定的條件下生效。例如最常見的滑鼠移到 HTML 元素上時讓文字變色、底色變色,這種產生的 :hover 效果,就是一種偽類。
至於被稱為偽類的由來不得而之,筆者猜測,可能是這種 CSS 語法是必須在指定的條件下生效,而不是像一般的 CSS class 一樣,只要寫上去就會生效,就像是假的類別一樣,所以才被稱作「偽類」。
依照 W3C 文件分類,偽類可依性質分為以下幾種:
以下筆者整理的表格中,點選選擇器一欄的連結,可直接連到 MDN 或 W3C 的專屬文件網頁,有比較詳細的介紹。
| 選擇器 | 性質 | 用途 / 生效條件 |
|---|---|---|
| :link | 連結 | 在瀏覽器歷史記錄中,使用者尚未點擊過的連結。 |
| :visited | 連結 | 在瀏覽器歷史記錄中,使用者已拜訪過的連結。 |
| :hover | 動作 | 使用者的滑鼠移動到元素上。 |
| :active | 動作 | 使用者的滑鼠點擊元素。 |
| :focus | 動作 | 讓元素得到焦點時觸發,例如。點擊文字輸入框。 |
| 選擇器 | 用途 / 生效條件 |
|---|---|
| :target | 瀏覽器網址的 # 錨點與網頁元素內的 id 相同時會產生效果。可用來強調、突顯段落標題。 |
| 選擇器 | 用途 / 生效條件 |
|---|---|
| :lang(language) | 搭配網頁元素中帶有 lang 語言屬性產生效果。「language」代表語言代碼,例如 en |
| 選擇器 | 用途 / 生效條件 |
|---|---|
| :enabled | 網頁元素禁止選取,例如 <input> 的 radio 或 checkobx、<select> 的 option 被禁止選取時。 |
| :disabled | 網頁元素禁止選取,例如 <input> 的 radio 或 checkobx、<select> 的 option 被禁止選取時。 |
| :checked | 例如 <input> 的 radio 或 checkobx、<select> 的 option 被選取時。 |
| 選擇器 | 用途 / 生效條件 |
|---|---|
| :root | 代表根元素,也就是 <html> 標籤。 |
| :nth-child(n) | 從每組兄弟元素從中選擇第 n 個節點。 |
| :nth-last-child(n) | 與 :nth-child 相反,它是從最後一個兄弟元素往前計算。 |
| :nth-of-type(n) | 在從相同類型的每组兄弟元素中選擇第 n 個節點。 |
| :nth-last-of-type(n) | 與 :nth-of-type 相反,它是從相同類型的每组兄弟元素中,從該組最後一個元素往前推算。 |
| :first-child | 從一組兄弟元素從中選擇第 1 個節點。 |
| :last-child | 從一組兄弟元素從中選擇第最後一個節點。 |
| :first-of-type | 在每组兄弟元素中選擇第 1 個節點。 |
| :last-of-type | 在每组兄弟元素中選擇最後個節點。 |
| :only-child | 沒有任何兄弟元素的節點。 |
| :only-of-type | 沒有其它相同類型的兄弟元素的節點。 |
| :empty | 沒有內容的節點。(可以只有注解標謙) |
表格中的 「n」代表選取的條件,最簡單的條件下它是它是一個從數字 1 開始的順序數字,有更複雜的條件,再請點選連結閱讀文件。
| 選擇器 | 用途 / 生效條件 |
|---|---|
| :not(selector) | 被 :not 指定的選擇器條件的元素會被排除,其餘元素會套用效果。「selector」代表選擇器條件。 |

【查看範例】
這裡是本次範例的基礎原始碼,HTML 基本上不會修改,會變動的部分只有第 15 行的地方,會把每個範例增加的範例放在這裡。

圖 a: 範例網頁畫面
原始的範例網頁看起來如上圖。是兩首詩,張繼的楓橋夜泊,以及文天祥的過零丁洋。
偽類只要掌握使用方法,就能很快上手。這邊只挑選可能在使用時機上會有疑慮的出來說明。
nth-child第 3 行:選取奇數行,文字變紅色。
第 7 行:選取偶數行,文字變藍色。
第 11 行:選取第一行,文字加底線。

圖 b: 範例 10-1 網頁畫面
有沒有發現那裡怪怪的?
第一眼就可能發現,.item:nth-child(1) 選擇器居然沒生效?
class 為 item 的「月落烏啼雙滿天」及「辛苦遭逢起一經,干戈寥落四周星」這兩行,並沒有加上底線。

那是因為,nth-child 它會先找到它的父元素,然後從父元素往下找,第一個節點是 .item 才會生效。
.item:nth-child(2n+1) {
color: red;
}
奇數行變成紅色,那沒問題,因為父元素下排序為奇數的節點,符合選擇器是 .item 就會生效。
我們將 HTML 改成以下,看看會發生什麼事。
第 4 行:把原 class 為 author 改成 item

圖 c: 範例 10-2 網頁畫面
修改的部分生效了。同樣的,使用 nth-child 來把奇數行文字變紅色、偶數行文字變藍色,也必須符合這種先找父元素,再找父元素下的節點,找到後比對選擇器正確才套用的規則。
nth-of-type
第 3 行:選取奇數行,文字變紅色。
第 7 行:選取偶數行,文字變藍色。
第 11 行:選取第二行,文字加底線。
以上 CSS 樣式不變,我們來看看下面例子。
它們唯一的差別是在作者那一行,一個使用的 HTML 的標籤是 <section>,另一個是使用 <div> 其餘不變。

圖 d: 範例 10-3 網頁畫面
都是使用相同的 CSS 語法,都是用 .item 這個 class 當選擇器元素,但是結果確是有很大的不同!
那是因為,nth-of-type 中的「type」指的就是 HTML 標籤。
它會先找到它的父元素,然後從父元素往下找,雖然也是找 .item,但是會以 type 來分群組。
以第一段詩來說:

nth-of-type 的解讀會是:
第 3 行:選取 <section class="item">、<div class="item"> 奇數行,文字變紅色。
第 7 行:選取 <section class="item">、<div class="item"> 偶數行,文字變藍色。
第 11 行:選取 <section class="item">、<div class="item"> 的第二行,文字加底線。
nth-child vs nth-of-type筆者在學習 CSS 的過程中,只曾對 nth-child、nth-of-type 有過疑問,猜想或許大部分的人可能也是如此,畢竟其它偽類語法只要查文件,通常可以直覺使用不會有差錯,但這兩種看似相同,但又不大一樣,特別提出來分享。
明天會暫時先離開 CSS 的世界,往 JavaScript 靠隴一些,來分享 JS 的監聽事件處理,要將「上一個」以及「下一個」按紐加上點擊事件,準備讓 Slider 開始「滑」起來。
文中範例可在 GitHub Page 閱讀。
原始碼可在 2022 鐵人賽專用 GitHub Repo 下載。